package graphics;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
 
import com.jogamp.opengl.util.Animator;
 
/**
 * Self-contained example (within a single class only to keep it simple) 
 * displaying a rotating quad
 * 
 * @author Julien Gouesse (http://tuer.sourceforge.net)
 * 
 * Source code under CC BY 3.0
 */
public class JoglExample {
 
    private static final class JoglExampleKeyListener extends KeyAdapter {
 
        private final JoglExample joglExample;
 
        private JoglExampleKeyListener(JoglExample joglExample) {
            this.joglExample = joglExample;
        }
 
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                joglExample.exit();
            }
        }
    }
 
    private static final class JoglExampleGLEventListener implements GLEventListener {
 
        private final JoglExample joglExample;
 
        private float rotateT = 0.0f;
 
        private GLU glu;
 
        private JoglExampleGLEventListener(JoglExample joglExample) {
            this.joglExample = joglExample;
        }
 
        @Override
        public void display(GLAutoDrawable gLDrawable) {
            final GL2 gl = gLDrawable.getGL().getGL2();
            gl.glClear(GL.GL_COLOR_BUFFER_BIT);
            gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
            gl.glLoadIdentity();
            gl.glTranslatef(0.0f, 0.0f, -5.0f);
 
            // rotate on the three axis
            gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
            gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
            gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
 
            // Draw A Quad
            gl.glBegin(GL2.GL_QUADS);       
            gl.glColor3f(0.0f, 1.0f, 1.0f);   // set the color of the quad
            gl.glVertex3f(-1.0f, 1.0f, 0.0f);   // Top Left
            gl.glVertex3f( 1.0f, 1.0f, 0.0f);   // Top Right
            gl.glVertex3f( 1.0f,-1.0f, 0.0f);   // Bottom Right
            gl.glVertex3f(-1.0f,-1.0f, 0.0f);   // Bottom Left
            // Done Drawing The Quad
            gl.glEnd();                                                     
 
            // increasing rotation for the next iteration                   
            rotateT += 0.2f; 
        }
 
        @Override
        public void init(GLAutoDrawable glDrawable) {
            GL2 gl = glDrawable.getGL().getGL2();
            glu = GLU.createGLU(gl);
            gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            gl.glClearDepth(1.0f);
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glDepthFunc(GL.GL_LEQUAL);
            gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
            ((Component) glDrawable).addKeyListener(new JoglExampleKeyListener(joglExample));
        }
 
        @Override
        public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
            GL2 gl = gLDrawable.getGL().getGL2();
            if (height <= 0) {
                height = 1;
            }
            float h = (float) width / (float) height;
            gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
            gl.glLoadIdentity();
            glu.gluPerspective(50.0f, h, 1.0, 1000.0);
            gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
            gl.glLoadIdentity();
        }
 
        @Override
        public void dispose(GLAutoDrawable gLDrawable) {
            // do nothing
        }
    }
 
    private final GLCanvas canvas;
 
    private final Frame frame;
 
    private final Animator animator;
 
    public JoglExample() {
        canvas = new GLCanvas();
        frame = new Frame("Jogl Quad drawing");
        animator = new Animator(canvas);
        canvas.addGLEventListener(new JoglExampleGLEventListener(this));
        frame.add(canvas);
        frame.setSize(640, 480);
        frame.setUndecorated(true);
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });
        frame.setVisible(true);
        animator.start();
        canvas.requestFocus();
    }
 
    public void exit() {
        animator.stop();
        frame.dispose();
        System.exit(0);
    }
 
    public static void main(String[] args) {
        // AWT methods have to be invoked on the AWT EDT
        EventQueue.invokeLater(new Runnable() {
 
            @Override
            public void run() {
                new JoglExample();
            }
        });
    }
}

